{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from matplotlib import pyplot as plt\n",
    "\n",
    "from sklearn.linear_model import LinearRegression"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "损失函数手动实现"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def compute_loss(X, y, theta):\n",
    "    if np.ndim(theta) == 1:\n",
    "        theta = theta[:, np.newaxis]\n",
    "\n",
    "    h_x = X.dot(theta) # h=θ^T dot X=θ0*x0+θ1*x1\n",
    "    # print(h_x.shape) # (97,2)x(2,1)=>(97,1)\n",
    "\n",
    "    m = y.size # 97\n",
    "    J_loss = 1./(2*m) * np.sum(np.square(h_x-y))\n",
    "    return J_loss"
   ]
  },
  {
   "cell_type": "markdown",
   "source": [
    "加载数据\n",
    "\n",
    "数据集简要数据说明：\n",
    "\n",
    "单元变量：人口 population\n",
    "\n",
    "target：profit"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(97, 2)\n",
      "[[1.     6.1101]\n",
      " [1.     5.5277]\n",
      " [1.     8.5186]\n",
      " [1.     7.0032]\n",
      " [1.     5.8598]] (97, 2)\n",
      "[[17.592 ]\n",
      " [ 9.1302]\n",
      " [13.662 ]\n",
      " [11.854 ]\n",
      " [ 6.8233]] (97, 1)\n"
     ]
    },
    {
     "data": {
      "text/plain": "Text(0, 0.5, 'Profit in $10,000s')"
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "cwd = '/home/xijian/pycharm_projects/Magic-NLPer/MachineLearning/'\n",
    "data_dir = cwd+'LinearRegression线性回归/data/'\n",
    "\n",
    "data = np.loadtxt(data_dir + 'linear_regression_data1.txt', delimiter=',')\n",
    "print(data.shape) # (97, 2)\n",
    "# X0 即theta0 对应的那一列\n",
    "X = np.c_[np.ones(data.shape[0]), data[:,0]]# (97,)=>(97, 2)\n",
    "print(X[:5], X.shape) # (97, 1)\n",
    "\n",
    "y = np.c_[data[:,1]] # (97,)=>(97, 1)\n",
    "print(y[:5], y.shape) # (97, 1)\n",
    "\n",
    "plt.scatter(X[:,1], y, s=30, c='r', marker='x', linewidths=1)\n",
    "plt.xlim(4, 24)\n",
    "plt.xlabel('Population of City in 10,000s')\n",
    "plt.ylabel('Profit in $10,000s')"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "查看一下 $\\theta$ =[0, 0]时的loss："
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "32.072733877455676\n"
     ]
    }
   ],
   "source": [
    "loss = compute_loss(X, y, [[0],[0]])\n",
    "print(loss)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "outputs": [],
   "source": [
    "# 参数theta默认初始化为0\n",
    "def gradient_descent(X, y, theta, alpha=0.01, num_iters=1000):\n",
    "    if np.ndim(theta) == 1:\n",
    "        theta = theta[:, np.newaxis]\n",
    "\n",
    "    m = y.size\n",
    "    J_losses = [] # 存放每个step过程中loss，便于绘图查看loss随着优化更新的变化\n",
    "\n",
    "    for _ in range(num_iters):\n",
    "        # 计算model输出\n",
    "        h_x = X.dot(theta) # (50,1)\n",
    "        # print(h_x.shape)\n",
    "        # 计算梯度并更新参数 X.T.dot(h_x-y):(2,50)x(50,1)=>(2,1)\n",
    "        grad = 1./m * X.T.dot(h_x-y) # (2,1)\n",
    "        theta = theta - alpha*grad # (2,1)\n",
    "        #print(theta)\n",
    "        # 计算损失\n",
    "        loss = compute_loss(X, y, theta)\n",
    "        J_losses.append(loss)\n",
    "\n",
    "    return (theta, J_losses)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "No handles with labels found to put in legend.\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "theta: [-3.63029144  1.16636235]\n"
     ]
    },
    {
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "theta, J_losses = gradient_descent(X, y, [[0],[0]], num_iters=1500) # 参数theta默认初始化为0\n",
    "print('theta:', theta.ravel()) # 拉平 (2,1)=>(2,)\n",
    "\n",
    "plt.plot(J_losses)\n",
    "plt.xlim(0)\n",
    "plt.ylabel('loss_mse(mean_square_error)')\n",
    "plt.xlabel('iter_steps')\n",
    "plt.legend()\n",
    "plt.show()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "markdown",
   "source": [
    "参数theta已经求出，现在画出拟合的直线："
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%% md\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[1. 5.]\n",
      " [1. 6.]\n",
      " [1. 7.]\n",
      " [1. 8.]\n",
      " [1. 9.]] (20, 2)\n",
      "[[2.20152031]\n",
      " [3.36788266]\n",
      " [4.53424501]\n",
      " [5.70060736]\n",
      " [6.86696971]] (20, 1)\n"
     ]
    },
    {
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "xx = np.arange(5, 25)\n",
    "xx = np.c_[np.ones(len(xx)), xx]\n",
    "print(xx[:5], xx.shape) # (20,2)\n",
    "yy = xx.dot(theta) # (20,2)x(2,1)=>(20,1)\n",
    "print(yy[:5], yy.shape)\n",
    "\n",
    "# 拟合曲线\n",
    "plt.plot(xx[:,1], yy, label='linear regression (gradient descent)')\n",
    "# 原始数据点\n",
    "plt.scatter(X[:,1], y, s=30, c='r', marker='x', linewidths=1)\n",
    "# sklearn 库中的线性回归模型拟合的曲线（与自己实现的对比）\n",
    "regr = LinearRegression()\n",
    "regr.fit(X[:,1].reshape(-1,1), y.ravel()) # X[:,1]的shape为(97,),reshape=>(97,1), y (97,1)=>拉平(97,)\n",
    "yy_regr = regr.intercept_ + regr.coef_*xx[:,1]\n",
    "plt.plot(xx[:,1], yy_regr, label='linear regression (sklearn)')\n",
    "\n",
    "plt.xlim(4,24)\n",
    "plt.legend(loc=4)\n",
    "plt.show()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(100, 2)\n",
      "(100, 28)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.preprocessing import PolynomialFeatures\n",
    "\n",
    "X = np.random.randn(100,2)\n",
    "print(X.shape)\n",
    "poly = PolynomialFeatures(6) # 最高次项为6次\n",
    "XX = poly.fit_transform(X) # X是有2个特征，XX有28个特征（含组合特征）\n",
    "print(XX.shape) # (118, 28)\n",
    "# 0次项：1个，1次项：2个，2次项：3个（x1^2,x2^2,x1x2），3次项：4个\n",
    "# 4次项：5个，5次项：6个，6次项：7个，一共28个特征\n"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}